/*
 *Programa Polinomios
 *Lenguajes de programación Grupo: 5
 *Integrantes:
   +Mora Contreras Enrique
   +Pajarito Vargas Antonio
   +Plata Silverio Víctor
   +Ríos Ferrer Kevin
 */
package Controlador;

import java.util.ArrayList;  
import java.util.Collections;  
import java.util.Comparator;  
import java.util.List;
/**/
public class Polinomio {
//----------Atributos------------
	public List<Monomio> poli;
        public String  mensaje="";
        public String  variable="";
        public String  impresion="";

//----------Constructores--------
    /*
     * El constructor recibe la string del polinomio
     * y la separa almacenando los datos en poli
     * 
     */
    public Polinomio(String cadena){
         poli= new ArrayList();
         
        if(cadena.isEmpty()){ 
             mensaje = "Escribe un polinomio";
             poli= null;
             return;
        }
        int x=0;
        x=cadena.codePointAt(0);
        if (!(x==43||x==45))
            cadena="+"+cadena;
            
         for(int i=0;i<cadena.length();i++){
             String s_coef="";
             int signo=0;
             //ASCII 48-57num, 46. 43+ 45-
             int c=cadena.codePointAt(i);
             while(i<cadena.length() && ((c>47&&c<58)||c==46||c==43||c==45)){
                 if (c==43||c==45) signo++;
                 if (signo>1) break;
                 s_coef+=(char)c+"";
                 i++;
                 if(!(i>=cadena.length())){
                     c=cadena.codePointAt(i);
                 }
             }
             //System.out.println("Coef antes del parse= "+s_coef);
             //parse

             if(s_coef.equals("")&& i==0) s_coef="1"; //para este caso: x+3
             if(s_coef.equals("+")) s_coef="1";       //para este caso: 4+x+2, +x^2
             if(s_coef.equals("-")) s_coef="-1";      //para este caso: -x+1          
             float f_coef=0;
             try{
                 f_coef=Float.parseFloat(s_coef);
             }
             catch (NumberFormatException nfe){
                   System.out.println("NumberFormatException: " + nfe.getMessage());
                   mensaje="ERROR polinomio no reconocido (Problema con coeficientes)";
                   poli= null;
                   return;
             }
             
             poli.add(new Monomio(f_coef,0));
             
             if(i>=cadena.length()){
                 break;
             } //rompe con 2X^2+1
             //ASCII 97-122 minusculas
             if (cadena.charAt(i)>=97 && cadena.charAt(i)<=122){
                 if(variable.equals("")){ //si no se ha registrado una variable
                     variable=cadena.charAt(i)+"";
                 }
                 if (!variable.equals(cadena.charAt(i)+"")){
                     mensaje="ERROR polinomio no reconocido (Muchas variables)";
                     poli= null;
                     return;
                 }
                 i++;
                 poli.get(poli.size()-1).exponente=1;
                 if(i>=cadena.length()){
                     break;
                 } //rompe con 2x^2+1x
                 //ASCII 94^
                 if(cadena.codePointAt(i)==94){
                     i++;
                     String s_exp="";
                     //ASCII 48-57num, 46. 43+ 45-
                     c=cadena.codePointAt(i);
                     while (i<cadena.length()&&(c>=48 && c<=57)){
                         s_exp+=(char)c+"";
                         i++;
                         if(!(i>=cadena.length())){
                         c=cadena.codePointAt(i);
                         }
                     }
                     //parse
                     int i_exp=0;
                     try{
                         i_exp=Integer.parseInt(s_exp);
                     }
                     catch (NumberFormatException nfe){
                           System.out.println("NumberFormatException: " + nfe.getMessage());
                           mensaje="ERROR polinomio no reconocido (Problema con exponentes)";
                           poli= null;
                           return;
                     }
                     poli.get(poli.size()-1).exponente=i_exp;

                 }
                 else poli.get(poli.size()-1).exponente=1; //si no tiene ^
             }//fin si son letras
             
             i--;
         }//fin del for
        mensaje="Polinomio reconocido";
        //Reduce
        if(variable.equals(""))variable="x";
        reducir();
        ordenar();
        System.out.println("Polinomio");
        imprimir();
        return;
    }
//----------Metodos--------------
    /*
     * De los elementos de un mismo polinomio
     * Toma los monomios con exponente igual y los suma
     * los elementos con coeficinte cero los elimina
     */
    public final void reducir (){
       for (int i=0;i<poli.size();i++){
            for (int j=1;j+i<poli.size();j++){
                //si el exponente es igual suma los coeficioentes
                if(poli.get(i).exponente==poli.get(i+j).exponente){
                    poli.get(i).coeficiente+=poli.get(i+j).coeficiente;
                    poli.remove(i+j);
                    j--;
                }
            }
            if(poli.get(i).coeficiente==0){
               poli.remove(i);
               i--;
            }
           
       }
    }
    /*
     * Ordena los polinomio respecto al exponente de menor a mayor
     * 
     */ 
    public final void ordenar (){
        //ordenamos la lista por codigo de empleado(variable tipo int)  
        Collections.sort(poli, new Comparator() {  
  
            public int compare(Object o1, Object o2) {  
                Monomio e1 = (Monomio) o1;  
                Monomio e2 = (Monomio) o2;  
                int codigo1 = e1.exponente;  
                int codigo2 = e2.exponente;  
  
                if (codigo1 > codigo2) {  
                    return 1;  
                } else if (codigo1 < codigo2) {  
                    return -1;  
                } else {  
                    return 0;  
                }  
            }  
        }); 
    } 
    /*
     * imprime en consola el polinomio
     * genera la String del polinomio que permite mostrarlo en la interfaz
     * 
     */
    public final void imprimir (){
        String signo="";
        impresion="";
        for (int i=poli.size()-1;i>=0;i--) { 
            if (poli.get(i).coeficiente>=0) signo="+"; else signo="";
            System.out.print(signo+poli.get(i).coeficiente+variable+"^"+poli.get(i).exponente); 
            impresion+=signo+poli.get(i).coeficiente+variable+"^"+poli.get(i).exponente;
        }
        System.out.println("");
        impresion+="\n";
    }
        
}
